<?php


namespace Anchu\Restful\Repository;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;

class Repository
{
    public $model;
    public $table;

    public function __construct($model)
    {
        $this->model = $model;
        // get table name
        $table = explode('\\', $model);
        $table = array_pop($table);
        $table = str_replace('Model', '', $table);
        $this->table = $this->uncamelize($table);
    }

    public function buildOrder(Builder $query, $orderBy = []): Builder
    {
        if (empty($orderBy)) return $query;

        foreach ($orderBy as $key => $val) {
            if (Str::upper($val) == 'DESC') {
                $query->orderByDesc($key);
            } else {
                $query->orderBy($key);
            }
        }
        return $query;
    }


    public function getList($where, $field = ['*'], $orderBy = [], $perPage = 0, $with = [], $page = 1)
    {
        $query = $this->model::query()->select($field);
        foreach ($where as $item) {
            if (in_array("in", $item)) {
                $query->whereIn($item[0], $item[2]);
            } else {
                $query->where([$item]);
            }
        }
        foreach ($with as $item) {
            $query->with($item);
        }
        $query = $this->buildOrder($query, $orderBy);
        return $page ? $query->paginate(perPage: $perPage, page: $page) : ($perPage ? $query->limit($perPage)->get() : $query->get());
    }

    public function getById($id, $with = [])
    {
        $query = $this->model::query();
        foreach ($with as $item) {
            $query->with($item);
        }
        return $query->find($id);
    }

    public function create($params)
    {
        return $this->model::query()->create($params);
    }

    public function update($id, $params, $where = [])
    {
        $query = $this->model::query();
        if (!empty($where)) {
            $query->where($where);
        }
        return $query->where('id', $id)->update($params);
    }

    public function delete($id, $where = [])
    {
        $query = $this->model::query();
        if (!is_array($id)) {
            $query->where('id', $id);
        } else {
            $where = $id;
        }
        if (!empty($where)) {
            $query->where($where);
        }
        return $query->delete();
    }

    /**
     * @function 表中是否包含某个字段
     * @param $column
     * @return bool
     */
    public function hasColumn($column)
    {
        return in_array($column, Schema::getColumnListing($this->table), true);
    }

    /**
     * 驼峰转换为下划线
     * @param $data
     * @return mixed
     */
    public function uncamelize($camelCaps, $separator = '_')
    {
        return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
    }
}
